package cn.chiship.framework.common.util;

import cn.chiship.framework.common.pojo.dto.SystemExceptionLogDto;
import cn.chiship.framework.common.pojo.dto.SystemOptionLogDto;
import cn.chiship.sdk.core.exception.custom.BusinessException;
import cn.chiship.sdk.core.util.DateUtils;
import cn.chiship.sdk.core.util.PrintUtil;
import cn.chiship.sdk.core.util.StringUtil;
import cn.chiship.sdk.framework.properties.ChishipDefaultProperties;
import cn.chiship.sdk.framework.util.SpringContextUtil;
import com.alibaba.druid.filter.config.ConfigTools;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author lj
 */
public class FrameworkUtil2 {

	private static final Logger logger = LoggerFactory.getLogger(FrameworkUtil2.class);

	private FrameworkUtil2() {
	}

	public static void formatErrorMessage(SystemExceptionLogDto systemExceptionLogDto) {
		logger.error("=================开始=====================");
		if (!StringUtil.isNullOrEmpty(systemExceptionLogDto.getUserName())) {
			logger.error("【操作人员】{}",
					systemExceptionLogDto.getUserName() + "(" + systemExceptionLogDto.getRealName() + ")");
		}
		logger.error("【操作时间】{}", DateUtils.getTime());
		logger.error("【请求码】{}", systemExceptionLogDto.getRequestId());
		logger.error("【错误描述】{}", systemExceptionLogDto.getDescription());
		logger.error("【请求接口】{}", systemExceptionLogDto.getBasePath() + systemExceptionLogDto.getUri());
		logger.error("【传入的参数】{}", systemExceptionLogDto.getParameter());
		logger.error("【错误栈描述】{}", systemExceptionLogDto.getErrorLocalizedMessage());
		logger.error("=================结束=====================");
	}

	public static void formatInfoMessage(SystemOptionLogDto systemOptionLogDto) {
		logger.info("=================开始=====================");
		if (!StringUtil.isNullOrEmpty(systemOptionLogDto.getUserName())) {
			logger.info("【操作人员】{}", systemOptionLogDto.getUserName() + "(" + systemOptionLogDto.getRealName() + ")");
		}
		logger.info("【操作时间】{}", DateUtils.dateTime(systemOptionLogDto.getStartTime(), DateUtils.YYYY_MM_DD_HH_MM_SS));
		logger.info("【花费时间】{}ms", systemOptionLogDto.getSpendTime());
		logger.info("【操作名称】{}", systemOptionLogDto.getDescription());
		logger.info("【函数名称】{}", systemOptionLogDto.getUri());
		logger.info("【传入的参数】{}", systemOptionLogDto.getParameter());
		logger.info("=================结束=====================");
	}

	public static ChishipDefaultProperties getChishipDefaultProperties() {
		return SpringContextUtil.getBean(ChishipDefaultProperties.class);
	}

	public static void generatorDruidPassword(String password) {
		try {
			ConfigTools.main(new String[] { password });
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static List<JSONObject> assemblyDataTree(String pid, List records) {
		return assemblyDataTree("pid", pid, records);
	}

	public static List<JSONObject> assemblyDataTree(String pidFiled, String pid, List records) {
		List<JSONObject> jsonObjects = new ArrayList<>();
		for (Object record : records) {
			Class<?> clazz = record.getClass();
			Field field = null;
			try {
				field = clazz.getDeclaredField(pidFiled);
			}
			catch (NoSuchFieldException e) {
				throw new BusinessException("没有属性：" + pidFiled);
			}
			if (ObjectUtils.isEmpty(field)) {
				return null;
			}
			field.setAccessible(true);
			Object value = null;
			try {
				value = field.get(record);
			}
			catch (IllegalAccessException e) {
				throw new BusinessException("不兼容的数据类型");
			}
			if (ObjectUtils.isEmpty(value)) {
				return null;
			}

			if (pid.equals(value)) {
				jsonObjects.add(JSON.parseObject(JSON.toJSONString(record)));
			}
		}
		for (JSONObject jsonObject : jsonObjects) {
			List<JSONObject> children = assemblyDataTree(pidFiled, jsonObject.getString("id"), records);
			if (!children.isEmpty()) {
				jsonObject.put("children", children);
			}
		}
		return jsonObjects;
	}

	/**
	 * 生成树状层级 四种清空 1.有孩子根节点添加数据 parentTreeNumber为空 treeNumber不为空 treeNumber 减号分割 最后+1
	 * 2.无孩子根节点添加数据 parentTreeNumber为空 treeNumber为空 treeNumber 0000 3.有孩子子节点添加数据
	 * parentTreeNumber不为空 treeNumber不为空 parentTreeNumber+“-”treeNumber 减号分割 最后+1
	 * 4.无孩子子节点添加数据 parentTreeNumber不为空 treeNumber为空 parentTreeNumber+"-0000"
	 * @param treeNumberInfo:parentTreeNumber-父级,treeNumber-本级最大
	 * @return
	 */
	public static String generateTreeNumber(Map<String, String> treeNumberInfo) {
		return generateTreeNumber(treeNumberInfo, 4);
	}

	/**
	 * 生成树状层级 四种清空 1.有孩子根节点添加数据 parentTreeNumber为空 treeNumber不为空 treeNumber 减号分割 最后+1
	 * 2.无孩子根节点添加数据 parentTreeNumber为空 treeNumber为空 treeNumber 0000 3.有孩子子节点添加数据
	 * parentTreeNumber不为空 treeNumber不为空 parentTreeNumber+“-”treeNumber 减号分割 最后+1
	 * 4.无孩子子节点添加数据 parentTreeNumber不为空 treeNumber为空 parentTreeNumber+"-0000"
	 * @param treeNumberInfo:parentTreeNumber-父级,treeNumber-本级最大
	 * @param digit 位数
	 * @return
	 */
	public static String generateTreeNumber(Map<String, String> treeNumberInfo, int digit) {
		String parentTreeNumber = null;
		String treeNumber = null;
		if (ObjectUtils.isNotEmpty(treeNumberInfo)) {
			parentTreeNumber = treeNumberInfo.get("parentTreeNumber");
			treeNumber = treeNumberInfo.get("treeNumber");
		}

		int count = 0;
		if (!StringUtil.isNullOrEmpty(treeNumber)) {
			count = Integer.parseInt(treeNumber.split("-")[treeNumber.split("-").length - 1], 16) + 1;
		}
		String result;
		String fmt = "%0" + digit + "x";
		if (StringUtil.isNullOrEmpty(parentTreeNumber) && !StringUtil.isNullOrEmpty(treeNumber)) {
			result = String.format(fmt, count);
		}
		else if (!StringUtil.isNullOrEmpty(parentTreeNumber) && !StringUtil.isNullOrEmpty(treeNumber)) {
			result = parentTreeNumber + "-" + String.format(fmt, count);
		}
		else if (!StringUtil.isNullOrEmpty(parentTreeNumber) && StringUtil.isNullOrEmpty(treeNumber)) {
			result = parentTreeNumber + "-" + String.format(fmt, count);
		}
		else {
			result = String.format(fmt, count);
		}
		return result;
	}

	/**
	 * 获得所有父级TreeNumber
	 * @param treeNumber
	 * @return
	 */
	public static List<String> getAllParentTreeNumber(String treeNumber) {
		List<String> fmtTreeNumbers = new ArrayList<>();
		String[] treeNumbers = treeNumber.split("-");
		for (Integer i = 0; i < treeNumbers.length; i++) {
			List<String> list = Arrays.asList(treeNumbers).subList(0, treeNumbers.length - i);
			fmtTreeNumbers.add(StringUtil.join(list, "-"));
		}
		Collections.reverse(fmtTreeNumbers);
		return fmtTreeNumbers;
	}

}
